home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / LINUX / MATH_EMU.ZIP / MATH_EMU / FPU_SIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1979-12-31  |  9.4 KB  |  349 lines

  1. /* FSIN, FCOS, FSINCOS */
  2.  
  3.  
  4. #include "types.h"
  5. #include "fpu_emul.h"
  6. #include "frame.h"
  7.  
  8. void fpu_sin_or_cos(struct fpemu *, int);
  9.  
  10. struct xtable {
  11.     int    sp_exp;
  12.     u_int    sp_m0,sp_m1,sp_single;
  13. } pitbl[]= {
  14.  
  15.   {  0xC0040000,0xC90FDAA2,0x2168C235,0x21800000 },
  16.   {  0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000 },
  17.   {  0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000 },
  18.   {  0xC0040000,0xB6365E22,0xEE46F000,0x21480000 },
  19.   {  0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000 },
  20.   {  0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000 },
  21.   {  0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000 },
  22.   {  0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000 },
  23.   {  0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000 },
  24.   {  0xC0040000,0x90836524,0x88034B96,0x20B00000 },
  25.   {  0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000 },
  26.   {  0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000 },
  27.   {  0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000 },
  28.   {  0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000 },
  29.   {  0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000 },
  30.   {  0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000 },
  31.   {  0xC0030000,0xC90FDAA2,0x2168C235,0x21000000 },
  32.   {  0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000 },
  33.   {  0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000 },
  34.   {  0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000 },
  35.   {  0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000 },
  36.   {  0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000 },
  37.   {  0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000 },
  38.   {  0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000 },
  39.   {  0xC0020000,0xC90FDAA2,0x2168C235,0x20800000 },
  40.   {  0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000 },
  41.   {  0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000 },
  42.   {  0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000 },
  43.   {  0xC0010000,0xC90FDAA2,0x2168C235,0x20000000 },
  44.   {  0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000 },
  45.   {  0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000 }, 
  46.   {  0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000 },
  47.   {  0x00000000,0x00000000,0x00000000,0x00000000 },
  48.   {  0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000 },
  49.   {  0x40000000,0xC90FDAA2,0x2168C235,0x9F800000 },
  50.   {  0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000 },
  51.   {  0x40010000,0xC90FDAA2,0x2168C235,0xA0000000 },
  52.   {  0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000 },
  53.   {  0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000 },
  54.   {  0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000 },
  55.   {  0x40020000,0xC90FDAA2,0x2168C235,0xA0800000 },
  56.   {  0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000 },
  57.   {  0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000 },
  58.   {  0x40030000,0x8A3AE64F,0x76F80584,0x21080000 },
  59.   {  0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000 },
  60.   {  0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000 },
  61.   {  0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000 },
  62.   {  0x40030000,0xBC7EDCF7,0xFF523611,0x21680000 },
  63.   {  0x40030000,0xC90FDAA2,0x2168C235,0xA1000000 },
  64.   {  0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000 },
  65.   {  0x40030000,0xE231D5F6,0x6595DA7B,0x21300000 },
  66.   {  0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000 },
  67.   {  0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000 },
  68.   {  0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000 },
  69.   {  0x40040000,0x8A3AE64F,0x76F80584,0x21880000 },
  70.   {  0x40040000,0x90836524,0x88034B96,0xA0B00000 },
  71.   {  0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000 },
  72.   {  0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000 },
  73.   {  0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000 },
  74.   {  0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000 },
  75.   {  0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000 },
  76.   {  0x40040000,0xB6365E22,0xEE46F000,0xA1480000 },
  77.   {  0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000 },
  78.   {  0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000 },
  79.   {  0x40040000,0xC90FDAA2,0x2168C235,0xA1800000 },
  80. };
  81.  
  82. static u_int sinA7[] = { 0xBD6AAA77,0xCCC994F5 };
  83. static u_int sinA6[] = { 0x3DE61209,0x7AAE8DA1 };
  84. static u_int sinA5[] = { 0xBE5AE645,0x2A118AE4 };
  85. static u_int sinA4[] = { 0x3EC71DE3,0xA5341531 };
  86. static u_int sinA3[] = { 0xBF2A01A0,0x1A018B59,0x00000000 };
  87. static u_int sinA2[] = { 0x3FF80000,0x88888888,0x888859AF };
  88. static u_int sinA1[] = { 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99 };
  89.  
  90. static u_int cosB8[] = { 0x3D2AC4D0,0xD6011EE3 };
  91. static u_int cosB7[] = { 0xBDA9396F,0x9F45AC19 };
  92. static u_int cosB6[] = { 0x3E21EED9,0x0612C972 };
  93. static u_int cosB5[] = { 0xBE927E4F,0xB79D9FCF };
  94. static u_int cosB4[] = { 0x3EFA01A0,0x1A01D423,0x00000000 };
  95. static u_int cosB3[] = { 0xBFF50000,0xB60B60B6,0x0B61D438 };
  96. static u_int cosB2[] = { 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E };
  97. static u_int cosB1[] = { 0xBF000000 };
  98.  
  99.  
  100. extern u_int TWOBYPI[];
  101. extern u_int TWOPI[];
  102.  
  103.  
  104.  
  105.  
  106. void fpu_sin_or_cos(struct fpemu *fe, int Adj)
  107. {
  108.  
  109.     static struct fpn X,S;
  110.     static struct fpn *d;
  111.     int     N,sign;
  112.     
  113.         
  114.  
  115.     CPYFPN(&X, &fe->fe_f2);
  116.  
  117.     /* reduce argument if necessary */
  118.     if(X.fp_exp > 5 || (X.fp_exp == 5 &&  X.fp_mant[0] >= (0xbc7e00 >> (31 - FP_LG))) ) {
  119.          CPYFPN(&fe->fe_f1,&fe->fe_f2);
  120.          fpu_explode(fe, &fe->fe_f2,FTYPE_EXT, TWOPI);
  121.          
  122.          d=fpu_rem(fe);
  123.          CPYFPN(&X ,d);
  124.          
  125.     };
  126.         if(X.fp_exp <= -40) {
  127.              switch(Adj) {
  128.                  case 0:
  129.                  
  130.                      return;
  131.                  case 1:
  132.                      fpu_const(&fe->fe_f2,0x32);
  133.                      return;
  134.                  };
  135.         };
  136.         
  137.         
  138.  
  139.     
  140.        
  141.         fpu_explode(fe, &fe->fe_f1, FTYPE_DBL, TWOBYPI);
  142.     CPYFPN(&fe->fe_f2,&X)
  143.         d = fpu_mul(fe);
  144.         fpu_implode(fe, d, FTYPE_LNG, &N);
  145.         
  146.       
  147.  
  148.     CPYFPN(&fe->fe_f1, &X);
  149.            fpu_explode(fe, &fe->fe_f2, FTYPE_EXT, &(pitbl[32+N].sp_exp));
  150.          fe->fe_f2.fp_sign= ! fe->fe_f2.fp_sign; 
  151.            d=fpu_add(fe);
  152.             
  153.         CPYFPN(&fe->fe_f1, d);
  154.         fpu_explode(fe, &fe->fe_f2, FTYPE_SNG, &(pitbl[32+N].sp_single));
  155.            fe->fe_f2.fp_sign= ! fe->fe_f2.fp_sign;           
  156.            d=fpu_add(fe);
  157.  
  158.           
  159.            
  160.            CPYFPN(&X, d);
  161.         CPYFPN(&fe->fe_f1, d);
  162.      CPYFPN(&fe->fe_f2, d);
  163.      d=fpu_mul(fe);
  164.      CPYFPN(&S, d);           
  165.  
  166.     
  167.     N+=Adj;
  168.     
  169.     
  170.     
  171.     if(N & 0xfffffffe !=  N) {
  172.     
  173.     
  174.     
  175.         sign=((N-1) >>1) & 0x00000001;
  176.     
  177.         CPYFPN(&fe->fe_f1, &S);
  178.         fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, cosB8);
  179.         d=fpu_mul(fe);
  180.         CPYFPN(&fe->fe_f2, d);
  181.             fpu_explode(fe, &fe->fe_f1, FTYPE_DBL, cosB7);
  182.             d=fpu_add(fe);
  183.             CPYFPN(&fe->fe_f2, d);
  184.         
  185.             CPYFPN(&fe->fe_f1, &S);
  186.         d=fpu_mul(fe);
  187.         CPYFPN(&fe->fe_f2,d);
  188.             fpu_explode(fe, &fe->fe_f1, FTYPE_DBL, cosB6);
  189.             d=fpu_add(fe);
  190.             CPYFPN(&fe->fe_f2, d);
  191.         
  192.          
  193.             CPYFPN(&fe->fe_f1, &S);
  194.         d=fpu_mul(fe);
  195.         CPYFPN(&fe->fe_f2,d);
  196.             fpu_explode(fe, &fe->fe_f1, FTYPE_DBL, cosB5);
  197.             d=fpu_add(fe);
  198.             CPYFPN(&fe->fe_f2, d);
  199.       
  200.      
  201.             CPYFPN(&fe->fe_f1, &S);
  202.         d=fpu_mul(fe);
  203.         CPYFPN(&fe->fe_f2,d);
  204.             fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, cosB4);
  205.             d=fpu_add(fe);
  206.             CPYFPN(&fe->fe_f2, d);
  207.  
  208.         CPYFPN(&fe->fe_f1, &S);
  209.         d=fpu_mul(fe);
  210.         CPYFPN(&fe->fe_f2,d);
  211.             fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, cosB3);
  212.             d=fpu_add(fe);
  213.             CPYFPN(&fe->fe_f2, d);
  214.  
  215.                                    
  216.             CPYFPN(&fe->fe_f1, &S);
  217.         d=fpu_mul(fe);
  218.         CPYFPN(&fe->fe_f2,d);
  219.             fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, cosB2);
  220.             d=fpu_add(fe);
  221.             CPYFPN(&fe->fe_f2, d);
  222.         
  223.          
  224.             CPYFPN(&fe->fe_f1, &S);
  225.         d=fpu_mul(fe);
  226.         CPYFPN(&fe->fe_f2,d);
  227.             fpu_explode(fe, &fe->fe_f1, FTYPE_SNG, cosB1);
  228.             d=fpu_add(fe);
  229.             CPYFPN(&fe->fe_f2, d);
  230.         
  231.          
  232.             CPYFPN(&fe->fe_f1, &S);
  233.         d=fpu_mul(fe);
  234.         CPYFPN(&fe->fe_f2,d);
  235.             fpu_const(&fe->fe_f1, 0x32);
  236.             d=fpu_add(fe);
  237.             CPYFPN(&fe->fe_f2, d);
  238.         
  239.             fe->fe_f2.fp_sign=sign;
  240.         
  241.         
  242.     
  243.     } else {
  244.     
  245.         sign=(N >> 1) & 0x00000001;
  246.         
  247.         
  248.         CPYFPN(&fe->fe_f1, &S);
  249.         fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, sinA7);
  250.         d=fpu_mul(fe);
  251.         CPYFPN(&fe->fe_f2, d);
  252.             fpu_explode(fe, &fe->fe_f1, FTYPE_DBL, sinA6);
  253.             d=fpu_add(fe);
  254.             CPYFPN(&fe->fe_f2, d);
  255.         
  256.             CPYFPN(&fe->fe_f1, &S);
  257.         d=fpu_mul(fe);
  258.         CPYFPN(&fe->fe_f2,d);
  259.             fpu_explode(fe, &fe->fe_f1, FTYPE_DBL, sinA5);
  260.             d=fpu_add(fe);
  261.             CPYFPN(&fe->fe_f2, d);
  262.         
  263.          
  264.             CPYFPN(&fe->fe_f1, &S);
  265.         d=fpu_mul(fe);
  266.         CPYFPN(&fe->fe_f2,d);
  267.             fpu_explode(fe, &fe->fe_f1, FTYPE_DBL, sinA4);
  268.             d=fpu_add(fe);
  269.             CPYFPN(&fe->fe_f2, d);
  270.       
  271.      
  272.             CPYFPN(&fe->fe_f1, &S);
  273.         d=fpu_mul(fe);
  274.         CPYFPN(&fe->fe_f2,d);
  275.             fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, sinA3);
  276.             d=fpu_add(fe);
  277.             CPYFPN(&fe->fe_f2, d);
  278.  
  279.  
  280.          
  281.             CPYFPN(&fe->fe_f1, &S);
  282.         d=fpu_mul(fe);
  283.         CPYFPN(&fe->fe_f2,d);
  284.             fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, sinA2);
  285.             d=fpu_add(fe);
  286.             CPYFPN(&fe->fe_f2, d);
  287.         
  288.          
  289.             CPYFPN(&fe->fe_f1, &S);
  290.         d=fpu_mul(fe);
  291.         CPYFPN(&fe->fe_f2,d);
  292.             fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, sinA1);
  293.             d=fpu_add(fe);
  294.             CPYFPN(&fe->fe_f2, d);
  295.         
  296.          
  297.             CPYFPN(&fe->fe_f1, &S);
  298.         d=fpu_mul(fe);
  299.         CPYFPN(&fe->fe_f2,d);
  300.         CPYFPN(&fe->fe_f1, &X);
  301.         d=fpu_mul(fe);
  302.         CPYFPN(&fe->fe_f2,d);
  303.         CPYFPN(&fe->fe_f1, &X);
  304.             d=fpu_add(fe);
  305.             CPYFPN(&fe->fe_f2, d);
  306.         
  307.             fe->fe_f2.fp_sign=sign;
  308.         
  309.             
  310.     
  311.     
  312.     };
  313.  
  314. }
  315. struct fpn *
  316. fpu_cos(fe)
  317.      struct fpemu *fe;
  318. {
  319.   fpu_sin_or_cos(fe, 1);
  320.   return &fe->fe_f2;
  321. }
  322.  
  323. struct fpn *
  324. fpu_sin(fe)
  325.      struct fpemu *fe;
  326. {
  327.   fpu_sin_or_cos(fe, 0);
  328.   return &fe->fe_f2;
  329. }
  330.  
  331. struct fpn *
  332. fpu_sincos(fe, regc)
  333.      struct fpemu *fe;
  334.      int regc;
  335. {
  336.   struct fpn X;
  337.   u_int *fpregs = &(fe->fe_fpframe->fpf_regs[regc*3]);
  338.   
  339.   
  340.   CPYFPN(&X, &fe->fe_f2);  
  341.   fpu_sin_or_cos(fe,1);
  342.   fpu_implode(fe, &fe->fe_f2, FTYPE_EXT, fpregs);
  343.  
  344.   
  345.   CPYFPN(&fe->fe_f2, &X);
  346.   fpu_sin_or_cos(fe,0);
  347.   return &fe->fe_f2;
  348. }
  349.